package com.vip.common.utils;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;

import java.io.File;
import java.io.InputStream;
import java.util.Objects;

/**
 * @author ASUS
 * @Date 2025/4/29 12:44
 * @Descripition 描述 ip  工具类
 */
@Slf4j
public class IPUtils {
    /**
     * 本地ip
     */
    private static final String LOCAL_IP = "127.0.0.1";
    /**
     * 未知ip
     */
    private static final String UNKNOWN_IP = "unknown";

    public static String getIpAddress(HttpServletRequest request) {
        if (request == null)
            return UNKNOWN_IP;
        String ip = request.getHeader("x-forwarded-for");
        // 如果通过多级反向代理，则取第一个ip地址
        if (StringUtils.isBlank(ip) || UNKNOWN_IP.equalsIgnoreCase(ip)) {
            // 通过nginx等反向代理软件，一般会添加一个x-forwarded-for
            ip = request.getHeader("Proxy-Client-IP");
        }
        // 通过apache代理软件，一般会添加一个x-forwarded-for
        if (StringUtils.isBlank(ip) || UNKNOWN_IP.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }
        // 通过apache代理软件，一般会添加一个x-forwarded-for
        if (StringUtils.isBlank(ip) || UNKNOWN_IP.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        // 通过apache代理软件，一般会添加一个x-forwarded-for
        if (StringUtils.isBlank(ip) || UNKNOWN_IP.equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
//         通过nginx等反向代理软件，一般会添加一个x-forwarded-for
        if (StringUtils.isBlank(ip) || UNKNOWN_IP.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? LOCAL_IP : ip;
    }

    /**
     *  根据ip获取详细地址
     */
    public static String getCityInfo(String ip) throws Exception {

        if (!Util.isIpAddress(ip)) {
            log.error("错误: 无效的ip地址");
            return null;
        }
        // 加载ip2region.db文件
        InputStream is = new PathMatchingResourcePatternResolver().getResources("ip2region.db")[0].getInputStream();
        File target = new File("ip2region.db");
        // 复制文件
        FileUtils.copyInputStreamToFile(is, target);
        is.close();

        if (StringUtils.isEmpty(String.valueOf(target))) {
            log.error("错误: 无效的ip2region.db文件");
            return null;
        }

        DbSearcher searcher = new DbSearcher(new DbConfig(), String.valueOf(target));

        try {
            DataBlock dataBlock = (DataBlock) searcher.getClass().getMethod("btreeSearch", String.class).invoke(searcher, ip);
            String ipInfo = dataBlock.getRegion();
            if (!StringUtils.isEmpty(ipInfo)) {
                ipInfo = ipInfo.replace("|0", "");
                ipInfo = ipInfo.replace("0|", "");
            }

            return ipInfo;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取网关ip
     * @param request 请求
     * @return {@link String }
     */
    public static String getGatewayIpAddress(ServerHttpRequest request) {
        HttpHeaders headers = request.getHeaders();
        String ip = headers.getFirst("x-forwarded-for");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if (ip.contains(",")) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = headers.getFirst("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = Objects.requireNonNull(request.getRemoteAddress()).getAddress().getHostAddress();
        }
        return ip;
    }
}
